/**
 * Copyright (C) 2004-2008 Giant Interective Group, Inc. All rights reserved.
 *
 * @(#) DESCrypto.java 1.0 2009-6-12
 */
package net.aying.util;

import java.io.File;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;

import net.aying.resources.Resources;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * DESCrypto 描述。
 * 
 * @author Fuchun
 * @version 1.0, 2009-6-12
 */
public class DESCrypto extends Crypto {
    
    @SuppressWarnings("unused")
    private static final Log log = LogFactory.getLog(DESCrypto.class);

    /**
     * 构造一个默认的 <code>DESCrypto</code> 新实例。
     */
    public DESCrypto() {
        this(DEFAULT_KEY_SPEC_STRING);
    }

    /**
     * 根据给定的密钥串构造一个 <code>DESCrypto</code> 新实例。
     * 
     * @param sKeySpec 给定的密钥串。
     */
    public DESCrypto(String sKeySpec) {
        setAlgorithm(ALGORITHM_DES);
        setSecretKeySpec(createSecretKeySpec(sKeySpec));
    }

    /* 创建一个 SecretKeySpec 实例对象。 */
    private SecretKeySpec createSecretKeySpec(String sKeySpec) {
        if (sKeySpec == null || "".equals(sKeySpec.trim()))
            sKeySpec = Resources.getMessage(DEFAULT_KEY_SPEC_STRING);
        SecretKeySpec secretKey = new SecretKeySpec(sKeySpec.getBytes(), 0, DESKeySpec.DES_KEY_LEN, ALGORITHM_DES);
        return secretKey;
    }

    /**
     * @see net.aying.util.Crypto#decrypt(java.lang.String)
     */
    public String decrypt(String encrypttext) {
        String result = null;
        SecureRandom sr = new SecureRandom();
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKeySpec(), sr);
            byte[] bytes = Hex.decodeHex(encrypttext.toCharArray());
            byte[] decryptBytes = cipher.doFinal(bytes);
            result = new String(decryptBytes);
        } catch (NoSuchPaddingException ex) {
            log.error(Resources.getMessage(Resources.UTIL_NO_SUCH_ALGORITHM, ALGORITHM_DES), ex);
        } catch (NoSuchAlgorithmException ex) {
            log.error(Resources.getMessage(Resources.UTIL_NO_SUCH_ALGORITHM, ALGORITHM_DES), ex);
        } catch(InvalidKeyException ex) {
            log.error(Resources.getMessage(Resources.UTIL_ERROR_INVALID_KEY), ex);
        } catch(DecoderException ex) {
            log.error("Hex#decodeHex ", ex);
        } catch(IllegalBlockSizeException ex) {
            log.error("Cipher#doFinal ", ex);
        } catch(BadPaddingException ex) {
            log.error(Resources.getMessage(Resources.UTIL_ERROR_ENCRYPT), ex);
        }
        return result;
    }

    /**
     * @see net.aying.util.Crypto#encrypt(java.lang.String)
     */
    public String encrypt(String plaintext) {
        String result = null;
        SecureRandom sr = new SecureRandom();
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
            cipher.init(Cipher.ENCRYPT_MODE, getSecretKeySpec(), sr);
            byte[] encryptBytes = cipher.doFinal(plaintext.getBytes());
            result = new String(Hex.encodeHex(encryptBytes));
        } catch (NoSuchPaddingException ex) {
            log.error(Resources.getMessage(Resources.UTIL_NO_SUCH_ALGORITHM, ALGORITHM_DES), ex);
        } catch (NoSuchAlgorithmException ex) {
            log.error(Resources.getMessage(Resources.UTIL_NO_SUCH_ALGORITHM, ALGORITHM_DES), ex);
        } catch(InvalidKeyException ex) {
            log.error(Resources.getMessage(Resources.UTIL_ERROR_INVALID_KEY), ex);
        } catch(IllegalBlockSizeException ex) {
            log.error("Cipher#doFinal ", ex);
        } catch(BadPaddingException ex) {
            log.error("Cipher#doFinal ", ex);
        }
        return result;
    }

    @Override
    protected File decryptFile(File encryptFilePath, String filePath) throws IOException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected File encryptFile(File txtFile, String encryptFilePath) throws IOException {
        // TODO Auto-generated method stub
        return null;
    }
}
